package org.example.gateway.filters;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.nacos.shaded.io.grpc.netty.shaded.io.netty.handler.codec.HeadersUtils;
import com.google.common.collect.Maps;
import org.example.common.core.constants.Constants;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.cors.reactive.CorsUtils;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

import java.util.Map;


/**
 * 跨域配置
 *
 */
@Component
public class GlobalCorsFilter implements WebFilter, Ordered {

    /**
     * 这里为支持的请求头，如果有自定义的header字段请自己添加
     */
    private static final String ALLOWED_HEADERS = "X-Requested-With, Content-Language, Content-Type, Authorization, credential, X-XSRF-TOKEN,grayTag";
    private static final String ALLOWED_METHODS = "GET,POST,PUT,DELETE,OPTIONS,HEAD";
    private static final String ALLOWED_ORIGIN = "*";
    private static final String ALLOWED_EXPOSE = "*";
    private static final String MAX_AGE = "18000L";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        if (CorsUtils.isCorsRequest(request)) {
            ServerHttpResponse response = exchange.getResponse();
            HttpHeaders headers = response.getHeaders();
            headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS);
            headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
            headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
            headers.add("Access-Control-Expose-Headers", ALLOWED_EXPOSE);
            headers.add("Access-Control-Max-Age", MAX_AGE);
            headers.add("Access-Control-Allow-Credentials", "true");
            if (request.getMethod() == HttpMethod.OPTIONS) {
                response.setStatusCode(HttpStatus.OK);
                return Mono.empty();
            }
        }

        if(isWebSocketRequest(exchange)){//websocket oauth认证处理
            String query=request.getURI().getQuery();
            String AUTHORIZATION=null;
            if(ObjectUtil.isNotEmpty(query)){
               String[] parStr=query.split("&");
               for(int i=0;i<parStr.length;i++){
                   if(ObjectUtil.isNotEmpty(parStr[i])){
                       String[] par=parStr[i].split("=");
                       if(Constants.HEADER.equals(par[0])){
                           AUTHORIZATION=par[1];
                           break;
                       }
                   }
               }
               if(ObjectUtil.isNotEmpty(AUTHORIZATION)){
                    ServerHttpRequest mutableReq = exchange.getRequest().mutate().header(Constants.HEADER, AUTHORIZATION).build();
                    ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build();
                    return chain.filter(mutableExchange);
               }
            }
        }
        return chain.filter(exchange);
    }





    public boolean isWebSocketRequest(ServerWebExchange exchange) {
        ServerHttpRequest request = exchange.getRequest();
        String upgradeHeader = request.getHeaders().getFirst("Upgrade");
        return "websocket".equalsIgnoreCase(upgradeHeader);
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}
